package com.hwy.chart.cursor

import android.graphics.*
import android.util.SparseArray
import androidx.annotation.ColorInt
import androidx.annotation.IntDef

/**
 * =======================================
 * 作者: hewenyu
 * 日期: 2022/5/10 16:32
 * 说明: 光标标签基本信息
 * =======================================
 */
open class CursorTag {

    companion object {

        /**
         * 纵向光标的标签
         */
        const val VERTICAL = 1

        /**
         * 横向光标的标签
         */
        const val HORIZONTAL = 2

        @IntDef(HORIZONTAL, VERTICAL)
        annotation class Orientation

    }

    private val tagPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            style = Paint.Style.FILL_AND_STROKE
            // 设置画笔对齐方式居中
            textAlign = Paint.Align.CENTER
        }
    }

    /**
     * 缓存标签文本
     * key: 固定两个key [VERTICAL]、[HORIZONTAL]
     * value: 对应横向/纵向的文本
     */
    private val tagMap by lazy {
        SparseArray<String>()
    }

    /**
     * 标签文本颜色
     */
    @ColorInt
    var tagTextColor = Color.WHITE

    /**
     * 标签文本大小
     */
    var tagTextSize = 20F

    /**
     * 标签文本间距
     */
    private var paddingLeft = 20F
    private var paddingTop = 10F
    private var paddingRight = 20F
    private var paddingBottom = 10F

    /**
     * 标签背景颜色
     */
    var tagColor = Color.parseColor("#563366FF")

    /**
     * 标签圆角大小
     */
    var tagCorner = 6F

    /**
     * 用于记录tag文本边框信息的矩形
     */
    private val textBounds by lazy {
        Rect()
    }

    /**
     * 保存tag绘制边框的矩形(支持圆角)
     */
    private val borderRect by lazy {
        RectF()
    }

    // region --------------------------------- 设置标签属性 ---------------------------------

    /**
     * 设置标签padding
     */
    fun setPadding(
        paddingLeft: Float,
        paddingTop: Float,
        paddingRight: Float,
        paddingBottom: Float
    ) {
        this.paddingLeft = paddingLeft
        this.paddingTop = paddingTop
        this.paddingRight = paddingRight
        this.paddingBottom = paddingBottom
    }

    /**
     * 设置标签文本
     *
     * @param verticalTag 纵向光标显示的tag
     * @param horizontalTag 横向光标显示的tag
     */
    fun setTag(verticalTag: String = "", horizontalTag: String = "") {
        tagMap.put(VERTICAL, verticalTag)
        tagMap.put(HORIZONTAL, horizontalTag)
    }

    // endregion ---------------------------------------------------------------------------

    // region --------------------------------- 标签绘制相关 ---------------------------------

    open fun draw(canvas: Canvas, x: Float, y: Float, @Orientation orientation: Int) {
        if (orientation == VERTICAL) {
            drawVerticalTag(canvas, x, y, tagMap.get(orientation))
        } else {
            drawHorizontalTag(canvas, x, y, tagMap.get(orientation))
        }
    }

    /**
     * 绘制横向光标显示的文本
     *
     * @param x tag标签左侧位置的坐标
     * @param y tag标签纵向中点位置的坐标
     */
    protected open fun drawHorizontalTag(canvas: Canvas, x: Float, y: Float, tag: String?) {
        if (tag.isNullOrEmpty()) {
            return
        }
        tag?.run {
            // 先计算 tag 文本的边框
            tagPaint.textSize = tagTextSize
            tagPaint.getTextBounds(this, 0, this.length, textBounds)
            // 设置tag标签背景边框
            borderRect.run {
                left = x
                right = y - textBounds.height() / 2F - paddingTop
                right = x + paddingLeft + paddingRight + textBounds.width()
                bottom = y + textBounds.height() / 2F + paddingBottom
            }
            // 绘制背景色
            tagPaint.color = tagColor
            canvas.drawRoundRect(borderRect, tagCorner, tagCorner, tagPaint)

            tagPaint.color = tagTextColor
            val baseline = tagPaint.fontMetrics.run {
                (descent - ascent) / 2 - descent
            }
            // 绘制tag文本
            canvas.drawText(
                this,
                x + paddingLeft + textBounds.width() / 2F,
                y + baseline,
                tagPaint
            )
        }
    }

    /**
     * 绘制纵向光标的文本
     *
     * @param x tag标签横向中间点的位置坐标
     * @param y tag标签顶部位置坐标
     */
    protected open fun drawVerticalTag(canvas: Canvas, x: Float, y: Float, tag: String?) {
        if (tag.isNullOrEmpty()) {
            return
        }
        tag?.run {
            // 先计算 tag 文本的边框
            tagPaint.textSize = tagTextSize
            tagPaint.getTextBounds(this, 0, this.length, textBounds)
            // 设置tag标签背景边框
            borderRect.run {
                left = x - textBounds.width() / 2F - paddingLeft
                top = y
                right = x + textBounds.width() / 2F + paddingRight
                bottom = y + paddingTop + paddingBottom + textBounds.height()
            }
            // 绘制背景色
            tagPaint.color = tagColor
            canvas.drawRoundRect(borderRect, tagCorner, tagCorner, tagPaint)

            tagPaint.color = tagTextColor
            val baseline = tagPaint.fontMetrics.run {
                (descent - ascent) / 2 - descent
            }
            // 绘制tag文本
            canvas.drawText(this, x, y + paddingTop + textBounds.height() / 2F + baseline, tagPaint)
        }
    }

    // endregion ---------------------------------------------------------------------------

}